package cn.tianyigps.tianyigpsm7clean.util;

import java.lang.reflect.Method;

/**
 * Created with IDEA
 *
 * @description: 实体属性赋值工具类
 * @author: cui.guibin
 * @create: 2019/4/18 14:57
 **/
public class BeanAssginUtil {

    public static void copyFieldJavaBean(Object target, Object source) {

        Class<?> targetClazz = target.getClass();
        Class<?> sourceClazz = source.getClass();
        // 得到method方法
        Method[] method1 = targetClazz.getMethods();
        Method[] method2 = sourceClazz.getMethods();

        int length1 = method1.length;
        int length2 = method2.length;
        if (length1 > 0 && length2 > 0) {
            // 创建一个get方法数组，专门存放class2的get方法。
            Method[] get = new Method[length2];
            for (int i = 0, j = 0; i < length2; i++) {
                if (method2[i].getName().indexOf("get") == 0) {
                    get[j] = method2[i];
                    ++j;
                }
            }

            for (int i = 0; i < get.length; i++) {
                try {
                    if (get[i] == null)// 数组初始化的长度多于get方法，所以数组后面的部分是null
                        continue;
                    // 得到get方法的值，判断时候为null，如果为null则进行下一个循环
                    Object value = get[i].invoke(source, new Object[]{});
                    if (null == value)
                        continue;
                    // 得到get方法的名称 例如：getXxxx
                    String getName = get[i].getName();
                    // 得到set方法的时候传入的参数类型，就是get方法的返回类型
                    Class<?> paramType = get[i].getReturnType();
                    Method getMethod = null;
                    try {
                        // 判断在class1中时候有class2中的get方法，如果没有则抛异常继续循环
                        getMethod = targetClazz.getMethod(getName, new Class[]{});
                    } catch (NoSuchMethodException e) {
                        continue;
                    }
                    // class1的get方法不为空并且class1中get方法得到的值为空，进行赋值，如果class1属性原来有值，则跳过
                    if (null == getMethod /*|| null != getMethod.invoke(target, new Object[]{})*/)
                        continue;
                    // 通过getName 例如getXxxx 截取后得到Xxxx，然后在前面加上set，就组装成set的方法名
                    String setName = "set" + getName.substring(3);
                    if ("setClass".equals(setName))
                        continue;
                    // 得到class1的set方法，并调用
                    Method setMethod = targetClazz.getMethod(setName, paramType);
                    setMethod.invoke(target, value);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
